/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.upf.grupE.DDBB;

import Learning.PruebaProperties;
import edu.upf.grupE.DDBB.Interfaces.DBAction;
import edu.upf.grupE.DDBB.Interfaces.DBManager;
import java.io.IOException;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.Unmarshaller;
import org.exolab.castor.xml.ValidationException;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.ResourceIterator;
import org.xmldb.api.base.ResourceSet;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.XMLResource;
import org.xmldb.api.modules.XQueryService;

/**
 *
 * @author xday666
 */
public class DDBBManager implements DBManager {

    static private DDBBManager dbmanager = null;
    static private Properties config;

    private DDBBManager() throws IOException {
        config = new Properties();
        config.load(PruebaProperties.class.getClassLoader().getResourceAsStream("config/Queries.properties"));
    }

    static public DDBBManager getInstance() throws IOException {

        if (dbmanager == null) {
            dbmanager = new DDBBManager();
        }
        return dbmanager;
    }

    /**
     *
     * @param aDBAction parametro
     * @return result
     */
    @Override
    public DDBBActionResult execute(final DBAction aDBAction) {
        DDBBActionResult resultado = new DDBBActionResult(true);
        String idQuery = aDBAction.getActionId();
        try {
            List lista = new Vector();
            String query = MessageFormat.format(config.getProperty(idQuery), aDBAction.getParameters());
            System.out.println(query);
            DataSource data = DataSource.getInstance();
            Collection col = data.getCollection();
            XQueryService service = (XQueryService) col.getService("XQueryService", "1.0");
            ResourceSet result = service.query(query);
            ResourceIterator i = result.getIterator();
            String xmlresult="";
            while (i.hasMoreResources()) {
                XMLResource r = (XMLResource) i.nextResource();
                Object tmp = null;
                try {
                    xmlresult =(String) r.getContent();
                    StringBuffer sbtmp = new StringBuffer();
                    sbtmp.append("edu.upf.grupE.Entities.");
                    sbtmp.append(idQuery.substring(0, idQuery.indexOf(".")));
                    tmp = Class.forName(sbtmp.toString()).newInstance();
                    tmp = Unmarshaller.unmarshal(tmp.getClass(), new StringReader(xmlresult));
                    lista.add(tmp);
                } catch (org.exolab.castor.xml.MarshalException ex) {
                    Logger.getLogger(DDBBManager.class.getName()).log(Level.SEVERE, null, ex);
                    resultado = new DDBBActionResult(false);
                    resultado.setException(ex);
                    resultado.setErrorMsg("El resultado no ha sido el esperado");
                    resultado.setResult(xmlresult);
                } catch (ClassNotFoundException ex) {
                    Logger.getLogger(DDBBManager.class.getName()).log(Level.SEVERE, null, ex);
                    resultado = new DDBBActionResult(false);
                    resultado.setException(ex);
                    resultado.setErrorMsg("No se tiene acceso a esta clase");
                    resultado.setResult(xmlresult);
                } catch (InstantiationException ex) {
                    Logger.getLogger(DDBBManager.class.getName()).log(Level.SEVERE, null, ex);
                    resultado = new DDBBActionResult(false);
                    resultado.setException(ex);
                    resultado.setErrorMsg("Problema al instanciar un objeto.");
                    resultado.setResult(xmlresult);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(DDBBManager.class.getName()).log(Level.SEVERE, null, ex);
                    resultado = new DDBBActionResult(false);
                    resultado.setException(ex);
                    resultado.setErrorMsg("No se tiene acceso a esta clase");
                    resultado.setResult(xmlresult);
                } catch (ValidationException ex) {
                    Logger.getLogger(DDBBManager.class.getName()).log(Level.SEVERE, null, ex);
                    resultado = new DDBBActionResult(false);
                    resultado.setException(ex);
                    resultado.setErrorMsg("XML mal formado");
                    resultado.setResult(xmlresult);
                }
            }
            if (resultado.isOk()) {
                resultado = new DDBBActionResult(true);
                resultado.setResult(lista);
            }
        } catch (XMLDBException ex) {
            Logger.getLogger(DDBBManager.class.getName()).log(Level.SEVERE, null, ex);
            resultado = new DDBBActionResult(false);
            resultado.setException(ex);
            resultado.setErrorMsg("Problema accediendo a la base de datos XML.");
        } catch (IOException ex) {
            Logger.getLogger(DDBBManager.class.getName()).log(Level.SEVERE, null, ex);
            resultado = new DDBBActionResult(false);
            resultado.setException(ex);
            resultado.setErrorMsg("Problema accediendo a la configuración de las Queries o Base de Datos.");
        }
        return resultado;
    }
}
